package com.marc.eden;

import android.Manifest;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.media.Image;
import android.media.ImageReader;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.getbase.floatingactionbutton.FloatingActionButton;
import com.getbase.floatingactionbutton.FloatingActionsMenu;

import java.io.ByteArrayOutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.HashMap;

public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnTouchListener {
    private String nickname;
    private EditText editTextAccountRegister;
    private EditText editTextPasswordRegister;
    private EditText editTextNicknameRegister;
    private TextView textViewToLogin;
    private Button buttonRegister;
    private View includeRegister;
    private TextView textViewToRegister;
    private Button buttonLogin;
    private EditText editTextAccountLogin;
    private EditText editTextPasswordLogin;
    private String account;
    private String password;
    private View includeLogin;
    private FloatingActionsMenu floatingActionsMenu;
    private FloatingActionButton floatingActionButtonCapture;
    private FloatingActionButton floatingActionButtonUser;
    private FloatingActionButton floatingActionButtonContacts;
    private TextView textView;
    private ImageView imageView;
    private ImageReader imageReader;
    private SurfaceView surfaceView;
    private SurfaceHolder surfaceHolder;
    private Camera camera;
    private Bitmap photo;
    private Face face;
    private User user;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 3);
        }

        face = new Face();

        user = new User("mo3fei", "hao3bi");

        initView();

    }

    public void detectFace() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                face.detect(photo);
            }
        }).start();
    }

    public void sendToServer() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
//                    URL url = new URL("http://10.0.2.2:8080/EdenServer/TestCommunication/Communication.jsp");
//                    URL url = new URL("http://192.168.1.101:8080/EdenServer/communicate");
//                    URL url = new URL("http://10.18.8.147:8080/EdenServer/eden");
                    URL url = new URL("http://140.143.35.110:8080/EdenServer/eden");
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    photo.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                    byte[] bytes = baos.toByteArray();
                    System.out.println(bytes.toString()+" !!!");
                    String image = Base64.encodeToString(bytes, Base64.URL_SAFE);
                    String account = user.getAccount();
                    String password = user.getPassword();
                    JSON.toJSONString(user);
                    HashMap<String, String> hashMap = new HashMap<String, String>();
                    hashMap.put("account", account);
                    hashMap.put("password", password);
                    hashMap.put("image", image);
                    String request = "result="+JSON.toJSONString(hashMap);
                    System.out.println(request);
                    HttpCommunication httpCommunication = new HttpCommunication(url, request);
                    httpCommunication.sendMessage();
                    System.out.println(httpCommunication.getResponse());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private void initView() {
        includeLogin = (View) findViewById(R.id.include_login);
        includeRegister = (View) findViewById(R.id.include_register);
        floatingActionsMenu = (FloatingActionsMenu) findViewById(R.id.floatingActionMenu);
        FloatingActionsMenu.OnFloatingActionsMenuUpdateListener floatingActionsMenuUpdateListener = new FloatingActionsMenu.OnFloatingActionsMenuUpdateListener() {
            @Override
            public void onMenuExpanded() {
                floatingActionButtonUser.setIcon(R.drawable.ic_person_white_24dp);
                floatingActionButtonContacts.setIcon(R.drawable.ic_people_white_24dp);
            }

            @Override
            public void onMenuCollapsed() {
                includeLogin.setVisibility(View.INVISIBLE);
                includeRegister.setVisibility(View.INVISIBLE);
            }
        };
        floatingActionsMenu.setOnFloatingActionsMenuUpdateListener(floatingActionsMenuUpdateListener);
        floatingActionButtonCapture = (FloatingActionButton) findViewById(R.id.floatingActionButton_capture);
        floatingActionButtonCapture.setOnClickListener(this);

        floatingActionButtonUser = (FloatingActionButton) findViewById(R.id.floatingActionButton_user);
        floatingActionButtonUser.setOnClickListener(this);

        floatingActionButtonContacts = (FloatingActionButton) findViewById(R.id.floatingActionButton_contacts);
        floatingActionButtonContacts.setOnClickListener(this);

        textView = (TextView) findViewById(R.id.textView);

        imageView = (ImageView) findViewById(R.id.imageView);

        imageReader = ImageReader.newInstance(600, 800, ImageFormat.JPEG, 15);
        imageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader imageReader) {
                Image image = imageReader.acquireNextImage();
                ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                byte[] bytes = new byte[buffer.remaining()];
                buffer.get(bytes);//由缓冲区存入字节数组
                Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                if (bitmap != null) {
                    Matrix matrix = new Matrix();
                    matrix.postRotate(-90);
                    matrix.postScale(-1, 1);
                    bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                    imageView.setImageBitmap(bitmap);
                }

                imageView.setVisibility(View.VISIBLE);
                textView.setVisibility(View.VISIBLE);

                photo = bitmap;
//                sendToServer();
                try {
                    matchFace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

//                detectFace();
            }
        }, new Handler(getMainLooper()));

        surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.setFixedSize(1080, 1920);
        surfaceHolder.setKeepScreenOn(true);
        surfaceHolder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {
                if (surfaceHolder == null) {
                    return;
                }
                camera = new Camera(MainActivity.this, surfaceHolder, imageReader);
            }

            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
                camera.destroyCamera();
            }
        });


        account = "";
        password = "";

        buttonLogin = (Button) findViewById(R.id.button_login);
        buttonLogin.setOnClickListener(this);
        editTextAccountLogin = (EditText) findViewById(R.id.editText_account_login);
        editTextPasswordLogin = (EditText) findViewById(R.id.editText_password_login);
        textViewToRegister = (TextView) findViewById(R.id.textView_to_register);
        textViewToRegister.setOnClickListener(this);
        textViewToRegister.setOnTouchListener(this);

        nickname = "";

        buttonRegister = (Button) findViewById(R.id.button_register);
        buttonRegister.setOnClickListener(this);
        editTextAccountRegister = (EditText) findViewById(R.id.editText_account_register);
        editTextPasswordRegister = (EditText) findViewById(R.id.editText_password_register);
        editTextNicknameRegister = (EditText) findViewById(R.id.editText_nickname);
        textViewToLogin = (TextView) findViewById(R.id.textView_to_login);
        textViewToLogin.setOnClickListener(this);
        textViewToLogin.setOnTouchListener(this);

    }
    
    private void sendLoginRequest() {
        if (editTextAccountLogin.getText().toString().isEmpty() ||
                editTextPasswordLogin.getText().toString().isEmpty()) {
            System.out.println("Please input account and password!");
            return;
        }
        account = editTextAccountLogin.getText().toString();
        password = editTextPasswordLogin.getText().toString();
        new Thread(new Runnable() {
            @Override
            public void run() {
                User user = new User(account, password);
                String end = user.login();
                System.out.println("send!!! "+end);

            }
        }).start();
    }

    private void sendRegisterRequest() {
        if (editTextAccountRegister.getText().toString().isEmpty() ||
                editTextPasswordRegister.getText().toString().isEmpty() ||
                editTextNicknameRegister.getText().toString().isEmpty()) {
            System.out.println("Please input account, password and nickname!");
            return;
        }
        account = editTextAccountRegister.getText().toString();
        password = editTextPasswordRegister.getText().toString();
        nickname = editTextNicknameRegister.getText().toString();
        new Thread(new Runnable() {
            @Override
            public void run() {
                User user = new User(account, password);
                user.setNickname(nickname);
                user.register();
                System.out.println("send!!! ");
            }
        }).start();
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.floatingActionButton_capture:
                camera.takePicture(imageReader);
                break;

            case R.id.floatingActionButton_user:
                floatingActionButtonUser.setIcon(R.drawable.ic_person_darkgray_24dp);
                floatingActionButtonContacts.setIcon(R.drawable.ic_people_white_24dp);
                includeLogin.setVisibility(View.VISIBLE);
                includeRegister.setVisibility(View.INVISIBLE);
                break;

            case R.id.floatingActionButton_contacts:
                floatingActionButtonUser.setIcon(R.drawable.ic_person_white_24dp);
                floatingActionButtonContacts.setIcon(R.drawable.ic_people_darkgray_24dp);
                includeLogin.setVisibility(View.INVISIBLE);
                includeRegister.setVisibility(View.INVISIBLE);
                break;
            
            case R.id.button_login:
                System.out.println("Click!");
                sendLoginRequest();
                Toast toastL = Toast.makeText(getApplicationContext(),
                        "logining!", Toast.LENGTH_LONG);
                toastL.show();
                includeLogin.setVisibility(View.INVISIBLE);
                includeRegister.setVisibility(View.INVISIBLE);
                break;

            case R.id.textView_to_register:
                System.out.println("register");
                includeLogin.setVisibility(View.INVISIBLE);
                includeRegister.setVisibility(View.VISIBLE);
                break;

            case R.id.button_register:
                System.out.println("Click!");
                sendRegisterRequest();
                Toast toastR = Toast.makeText(getApplicationContext(),
                        "register success!", Toast.LENGTH_LONG);
                toastR.show();
                includeLogin.setVisibility(View.VISIBLE);
                includeRegister.setVisibility(View.INVISIBLE);
                break;

            case R.id.textView_to_login:
                System.out.println("login");
                includeLogin.setVisibility(View.VISIBLE);
                includeRegister.setVisibility(View.INVISIBLE);
                break;

            default:
                break;
        }
    }

    public void matchFace() throws InterruptedException {
        System.out.println("matching face!!!");
        final String[] un = new String[1];
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                photo.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                byte[] bytes = baos.toByteArray();
                String image = Base64.encodeToString(bytes, Base64.URL_SAFE);
                try {
//            URL url = new URL("http://192.168.1.101:8080/EdenServer/communicate");
//            URL url = new URL("http://"+Utils.SERVER_ADDRESS+":3306/EdenServer/eden");
//                    URL url = new URL("http://10.18.8.147:8080/EdenServer/eden");
                    URL url = new URL("http://140.143.35.110:8080/EdenServer/eden");
                    String request = "func=recognize"+"&image="+image;
                    HttpCommunication httpCommunication = new HttpCommunication(url,request);
                    httpCommunication.sendMessage();
                    System.out.println("!!!!!");

//                    System.out.println(httpCommunication.getResponse());

//                    String userNa = httpCommunication.getResponse().substring(httpCommunication.getResponse().indexOf("is "));
//                    Toast.makeText(MainActivity.this,"-----",Toast.LENGTH_SHORT).show();
                    un[0] = httpCommunication.getResponse();



                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }
            }
        });

        thread.start();
        thread.join();
        Toast.makeText(MainActivity.this, un[0],Toast.LENGTH_SHORT).show();
        un[0] = null;
//        Log.d("dfdfdfdfd",un);

    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        switch (view.getId()) {
            case R.id.textView_to_register:
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        System.out.println("down");
                        textViewToRegister.setTextColor(Color.BLUE);
                        break;

                    case MotionEvent.ACTION_UP:
                        System.out.println("up");
                        textViewToRegister.setTextColor(Color.WHITE);
                        break;

                    default:
                        break;

                }
                break;

            case R.id.textView_to_login:
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        System.out.println("down");
                        textViewToLogin.setTextColor(Color.BLUE);
                        break;

                    case MotionEvent.ACTION_UP:
                        System.out.println("up");
                        textViewToLogin.setTextColor(Color.WHITE);
                        break;

                    default:
                        break;

                }
                break;

            default:
                break;

        }
        return false;

    }
}
